package parser;

import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.junit.Test;

public class TestParserMain {
	
	//@author A0085082E
	@Test
	public void test() {

		test_set();
		test_setDate();
		test_setTime();
		test_reduce();
		test_isUselessCommand();
	}

	private void test_set(){

		ParserMain.setCommand("test1");
		assertEquals("Test set command", ParserMain.command, "test1");

		ParserMain.setTaskName("test2");
		assertEquals("Test set task name", ParserMain.taskName, "test2");

		ParserMain.setDescription("test3");
		assertEquals("Test set description", ParserMain.description, "test3");

		ParserMain.setLength(4);
		assertEquals("Test set length", ParserMain.length, 4);

		ParserMain.setType(5);
		assertEquals("Test set Type", ParserMain.type, 5);

		//Test if setContainsDescription works properly
		ParserMain.setContainsDescription(true);
		assertTrue(ParserMain.containsDescription);

		ParserMain.setContainsDescription(false);
		assertFalse(ParserMain.containsDescription);

		//Test if setProper works properly
		ParserMain.setProper(true);
		assertTrue(ParserMain.setProper);

		ParserMain.setProper(false);
		assertFalse(ParserMain.setProper);

	}


	/*
	 * Accepts only:
	 * 
	 * 1. 0<date<32
	 * 2. 0< month<13
	 */
	private void test_setDate(){

		Calendar test = new GregorianCalendar();

		//invalid date
		ParserMain.setProper(ParserMain.setDate("0", test));
		assertFalse(ParserMain.setProper);

		test_dayValidity();
		test_invalidMonth();



	}


	/*
	 * Accepts only:
	 * 
	 * 1. 0<= hour <=23
	 * 2. 0<= minute <=59
	 */
	private void test_setTime(){

		test_Hour();
		test_Minute();
		test_setTimeIfHHMMSS();
	}
	
	private void test_reduce(){
		String abc = ParserMain.reduceToInt("iw1j2h3b4nb5h6@@@7**8((90##");
		assertEquals("A string of number!", abc, "1234567890");
		
		abc = ParserMain.reduceToIntAndChar("~~1122Angel&Demons8899~~");
		assertEquals("A string of number and char!", abc, "1122AngelDemons8899");
		
	}
	
	private void test_isUselessCommand(){
		assertTrue(ParserMain.isUselessCommand("#(@("));
		assertFalse(ParserMain.isUselessCommand("a#(@("));
		assertFalse(ParserMain.isUselessCommand("0#(@("));
	}

	private void test_dayValidity(){

		Calendar test = new GregorianCalendar();

		//day == 0
		ParserMain.setProper(ParserMain.setDate("00/01/01", test));
		assertFalse(ParserMain.setProper);

		//day == 32
		ParserMain.setProper(ParserMain.setDate("32/01/01", test));
		assertFalse(ParserMain.setProper);

		//day == 1
		ParserMain.setProper(ParserMain.setDate("01/01/01", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Day is 1", test.get(Calendar.DATE), 1);

		//day == 31
		ParserMain.setProper(ParserMain.setDate("31/01/01", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Day is 31", test.get(Calendar.DATE), 31);


	}

	//There is no test for negative because there won't be any sign in the number string
	private void test_invalidMonth(){

		Calendar test = new GregorianCalendar();

		//Month == 0
		ParserMain.setProper(ParserMain.setDate("01/00/01", test));
		assertFalse(ParserMain.setProper);

		//Month == 13
		ParserMain.setProper(ParserMain.setDate("31/13/01", test));
		assertFalse(ParserMain.setProper);

		//Month == 1
		ParserMain.setProper(ParserMain.setDate("01/01/01", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Month is 1", test.get(Calendar.MONTH), 0);

		//Month == 12
		ParserMain.setProper(ParserMain.setDate("01/12/01", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Month is 12", test.get(Calendar.MONTH), 11);


	}

	private static void test_Hour(){

		Calendar test = new GregorianCalendar();

		//hour == 24
		ParserMain.setProper(ParserMain.setDate("2400", test));
		assertFalse(ParserMain.setProper);

		//hour == 0
		ParserMain.setProper(ParserMain.setTime("0000", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Hour is 0", test.get(Calendar.HOUR_OF_DAY), 0);

		//hour == 23
		ParserMain.setProper(ParserMain.setTime("2300", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Hour is 23", test.get(Calendar.HOUR_OF_DAY), 23);


	}

	private static void test_Minute(){

		Calendar test = new GregorianCalendar();

		//Minute == 60
		ParserMain.setProper(ParserMain.setTime("2460", test));
		assertFalse(ParserMain.setProper);

		//Minute == 0
		ParserMain.setProper(ParserMain.setTime("0000", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Minute is 0", test.get(Calendar.MINUTE), 0);

		//hour == 59
		ParserMain.setProper(ParserMain.setTime("2359", test));
		assertTrue(ParserMain.setProper);
		assertEquals("Minute is 59", test.get(Calendar.MINUTE), 59);


	}
	
	private static void test_setTimeIfHHMMSS(){
		
		Calendar test = new GregorianCalendar();

		//SS== 00
		ParserMain.setProper(ParserMain.setTime("2333", test));
		assertEquals("Second", test.get(Calendar.SECOND), 0);
		
		//SS== 59
		ParserMain.setProper(ParserMain.setTime("2359", test));
		assertEquals("Second", test.get(Calendar.SECOND), 59);
				
	}

	

}
